<template>
  <div class="topology-diagram">
    <div class="controls">
      <el-button type="primary" @click="updateTopology">刷新状态</el-button>
      <el-button @click="exportTopology">导出拓扑图</el-button>
    </div>
    <div id="chart" style="height: 760px;" ref="chart" class="chart"></div>
    <el-dialog :visible.sync="dialogVisible" title="流量趋势图" width="70%">
      <div id="trafficChart" ref="trafficChart" class="traffic-chart"></div>
    </el-dialog>
  </div>
</template>

<script>
import * as echarts from 'echarts';
import html2canvas from 'html2canvas';
import FileSaver from 'file-saver';
import MonitorService from '@/utils/MonitorService';

export default {
  name: 'TopologyDiagram',
  data() {
    return {
      chartInstance: null,
      trafficChartInstance: null,
      dialogVisible: false,
      monitorService: new MonitorService(),
      devicesStatus: {},
      linksStatus: {},
      // 区域定义
      areas: [
        {
          name: '云营商',
          subName: 'HAPPY',
          devices: ['融合路由', '基础网关', 'S业务综合网关'],
          position: { x: 100, y: 50, width: 300, height: 200 }
        },
        {
          name: '易电井',
          subName: 'POR ONLY',
          devices: ['万科MO交换机', 'OAT服务器', '监控NVR'],
          position: { x: 450, y: 50, width: 300, height: 200 }
        },
        {
          name: '公共区域',
          subName: '充电AP',
          devices: ['门禁', 'IP端机', '电子水管', 'IP广播', '摄像头'],
          position: { x: 100, y: 300, width: 300, height: 200 }
        },
        {
          name: '房间',
          subName: '模拟器机',
          devices: ['SOS', 'RCU暗控', '控制柜'],
          position: { x: 450, y: 300, width: 300, height: 200 }
        },
        {
          name: '前台办公室',
          subName: 'MIDU',
          devices: ['视频会议', 'PC', '打印机', '闹钟表'],
          position: { x: 275, y: 550, width: 300, height: 200 }
        }
      ],
      // 全局链路
      globalLinks: [
        { source: '融合路由', target: 'OAT服务器', lineType: 'fiber' },
        { source: '基础网关', target: 'IP端机', lineType: 'fiber' },
        { source: 'S业务综合网关', target: '视频会议', lineType: 'isp' },
        { source: '万科MO交换机', target: '门禁', lineType: 'website' }
      ]
    };
  },
  mounted() {
    this.$nextTick(() => {
      if (this.$refs.chart) {
        this.chartInstance = echarts.init(this.$refs.chart);
        this.loadInitialData();
        this.loadTopology();
        
        // 添加点击事件
        this.chartInstance.on('click', params => {
          if (params.dataType === 'edge') {
            this.showTrafficChart(params.data.source, params.data.target);
          }
        });
      }
    });
  },
  methods: {
    loadInitialData() {
      const realTimeData = this.monitorService.getRealTimeData();
      
      // 初始化设备状态
      this.devicesStatus = {};
      realTimeData.devices.forEach(device => {
        this.devicesStatus[device.name] = device.status;
      });
      
      // 初始化链路状态
      this.linksStatus = {};
      realTimeData.links.forEach(link => {
        const key = `${link.source}-${link.target}`;
        this.linksStatus[key] = {
          usage: link.usage,
          status: link.status
        };
      });
    },
    loadTopology() {
      const nodes = [];
      const links = [];
      
      // 1. 添加区域节点
      this.areas.forEach(area => {
        // 添加区域节点（作为分组标题）
        nodes.push({
          name: area.name,
          x: area.position.x + area.position.width / 2,
          y: area.position.y - 20,
          symbolSize: 0,
          itemStyle: { color: 'transparent' },
          label: {
            show: true,
            fontSize: 16,
            fontWeight: 'bold',
            color: '#333'
          }
        });
        
        // 添加子区域节点
        nodes.push({
          name: area.subName,
          x: area.position.x + area.position.width / 2,
          y: area.position.y,
          symbolSize: 0,
          itemStyle: { color: 'transparent' },
          label: {
            show: true,
            fontSize: 14,
            color: '#666'
          }
        });
        
        // 2. 添加设备节点（在区域内均匀分布）
        const deviceCount = area.devices.length;
        const gridCols = Math.min(3, deviceCount); // 每行最多3个设备
        const gridWidth = area.position.width / (gridCols + 1);
        const gridHeight = area.position.height / (Math.ceil(deviceCount / gridCols) + 1);
        
        area.devices.forEach((device, index) => {
          const row = Math.floor(index / gridCols);
          const col = index % gridCols;
          
          nodes.push({
            name: device,
            x: area.position.x + (col + 1) * gridWidth,
            y: area.position.y + (row + 1) * gridHeight + 20,
            value: [area.position.x + (col + 1) * gridWidth, area.position.y + (row + 1) * gridHeight],
            category: this.getDeviceCategory(device),
            symbolSize: 40,
            itemStyle: {
              color: this.getDeviceColor(device)
            }
          });
          
          // 添加区域到设备的连接（虚线）
          links.push({
            source: area.subName,
            target: device,
            lineStyle: {
              type: 'dashed',
              width: 1,
              color: '#aaa'
            }
          });
        });
      });
      
      // 3. 添加全局链路
      this.globalLinks.forEach(link => {
        links.push({
          source: link.source,
          target: link.target,
          lineStyle: this.getLinkStyle(link.source, link.target, link.lineType)
        });
      });
      
      // 4. 配置拓扑图选项
      const option = {
        tooltip: {
          trigger: 'item',
          formatter: (params) => {
            if (params.dataType === 'edge') {
              const key = `${params.data.source}-${params.data.target}`;
              const status = this.linksStatus[key]?.status || '正常';
              const usage = this.linksStatus[key]?.usage || 0;
              return `链路: ${params.data.source} → ${params.data.target}<br/>
                      状态: <span style="color:${this.getStatusColor(status)}">${status}</span><br/>
                      使用率: ${usage}%`;
            }
            const status = this.devicesStatus[params.data.name] || '正常';
            return `设备: ${params.data.name}<br/>
                    状态: <span style="color:${this.getStatusColor(status)}">${status}</span>`;
          }
        },
        legend: {
          data: ['服务器', '交换机', '路由器', '网关', '终端设备'],
          bottom: 10
        },
        animation: true,
        series: [{
          type: 'graph',
          layout: 'none',
          data: nodes,
          links: links,
          categories: [
            { name: '服务器', symbol: 'rect', itemStyle: { color: '#5470c6' } },
            { name: '交换机', symbol: 'diamond', itemStyle: { color: '#91cc75' } },
            { name: '路由器', symbol: 'roundRect', itemStyle: { color: '#fac858' } },
            { name: '网关', symbol: 'triangle', itemStyle: { color: '#ee6666' } },
            { name: '终端设备', symbol: 'circle', itemStyle: { color: '#73c0de' } }
          ],
          roam: true,
          zoom: 1,
          label: {
            show: true,
            position: 'bottom',
            distance: 5,
            formatter: '{b}'
          },
          edgeSymbol: ['none', 'arrow'],
          edgeSymbolSize: 8,
          lineStyle: {
            color: '#aaa',
            curveness: 0.2
          },
          emphasis: {
            focus: 'adjacency',
            lineStyle: {
              width: 3
            }
          }
        }],
        graphic: this.areas.map(area => {
          return {
            type: 'rect',
            z: -1,
            shape: {
              x: area.position.x,
              y: area.position.y + 10,
              width: area.position.width,
              height: area.position.height
            },
            style: {
              fill: 'rgba(255, 255, 255, 1)',
              stroke: '#fff',
              lineWidth: 2
            }
          };
        })
      };
      
      this.chartInstance.setOption(option);
      window.addEventListener('resize', this.handleResize);
    },
    handleResize() {
      if (this.chartInstance) {
        this.chartInstance.resize();
      }
    },
    updateTopology() {
      // 模拟更新设备状态
      this.monitorService.updateDeviceStatus('融合路由', '正常');
      this.monitorService.updateDeviceStatus('OAT服务器', '正常');
      this.monitorService.updateLinkStatus('融合路由', 'OAT服务器', 45, '正常');
      
      this.loadInitialData();
      this.loadTopology();
      this.$message.success('拓扑状态已更新');
    },
    exportTopology() {
      html2canvas(this.$refs.chart).then(canvas => {
        canvas.toBlob(blob => {
          FileSaver.saveAs(blob, '核心机房拓扑图.png');
        });
      });
    },
    getDeviceColor(deviceName) {
      const status = this.devicesStatus[deviceName] || '正常';
      return this.getStatusColor(status);
    },
    getStatusColor(status) {
      switch (status) {
        case '故障': return '#F56C6C';
        case '警告': return '#E6A23C';
        case '离线': return '#909399';
        default: return '#67C23A';
      }
    },
    getDeviceCategory(deviceName) {
      if (deviceName.includes('服务器')) return 0;
      if (deviceName.includes('交换')) return 1;
      if (deviceName.includes('路由')) return 2;
      if (deviceName.includes('网关')) return 3;
      return 4; // 终端设备
    },
    getLinkStyle(source, target, lineType) {
      const key = `${source}-${target}`;
      const status = this.linksStatus[key]?.status || '正常';
      
      let lineStyle = {
        width: 2,
        color: this.getStatusColor(status)
      };
      
      // 根据线路类型设置不同样式
      switch (lineType) {
        case 'fiber':
          lineStyle.type = 'solid';
          break;
        case 'website':
          lineStyle.type = 'dotted';
          break;
        case 'isp':
          lineStyle.type = 'dashed';
          break;
      }
      
      return lineStyle;
    },
    showTrafficChart(source, target) {
      this.dialogVisible = true;
      
      this.$nextTick(() => {
        if (!this.trafficChartInstance) {
          this.trafficChartInstance = echarts.init(this.$refs.trafficChart);
        }
        
        // 模拟流量数据
        const trafficOption = {
          title: {
            text: `${source} 到 ${target} 的流量趋势`,
            left: 'center'
          },
          tooltip: {
            trigger: 'axis'
          },
          legend: {
            data: ['流入', '流出'],
            bottom: 10
          },
          grid: {
            left: '3%',
            right: '4%',
            bottom: '15%',
            containLabel: true
          },
          xAxis: {
            type: 'category',
            data: ['00:00', '04:00', '08:00', '12:00', '16:00', '20:00', '24:00']
          },
          yAxis: {
            type: 'value',
            name: '流量 (Mbps)'
          },
          series: [
            {
              name: '流入',
              type: 'line',
              data: [120, 132, 101, 134, 90, 230, 210],
              smooth: true,
              lineStyle: {
                width: 3,
                color: '#5470C6'
              }
            },
            {
              name: '流出',
              type: 'line',
              data: [85, 93, 90, 95, 70, 120, 110],
              smooth: true,
              lineStyle: {
                width: 3,
                color: '#91CC75'
              }
            }
          ]
        };
        
        this.trafficChartInstance.setOption(trafficOption);
      });
    }
  },
  beforeDestroy() {
    window.removeEventListener('resize', this.handleResize);
  }
};
</script>

<style scoped>
.topology-diagram {
  width: 100%;
  height: 100%;
  position: relative;
  background-color: #f5f7fa;
  padding: 15px;
  box-sizing: border-box;
  border-radius: 6px;
  box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
}

.controls {
  margin-bottom: 15px;
  display: flex;
  justify-content: flex-end;
  gap: 10px;
}

.chart {
  width: 100%;
  height: 100%;
  background-color: white;
  border-radius: 4px;
  border: 1px solid #ebeef5;
}

.traffic-chart {
  width: 100%;
  height: 450px;
}
</style>